home *** CD-ROM | disk | FTP | other *** search
/ Shareware Super Platinum 8 / Shareware Super Platinum 8.iso / mac / WIN_PRO / DS-1.ZIP;1 / PREPROC.ZIP / P_OUT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-10  |  7.6 KB  |  230 lines

  1. #include "../preproc/preproc.h"
  2. #include "../preproc/pproto.h"
  3.  
  4. int line_cntrl;
  5.  
  6. /*
  7.  * output - output preprocessed tokens for the current file.
  8.  */
  9. novalue output(out_file)
  10. FILE *out_file;
  11.    {
  12.    struct token *t, *t1;
  13.    struct token *saved_whsp;
  14.    char *fname;
  15.    char *s;
  16.    int line;
  17.    int nxt_line;
  18.    int trail_nl;  /* flag: trailing character in output is a new-line */
  19.    int  blank_ln;  /* flag: output ends with blank line */
  20.  
  21.    fname = "";
  22.    line = -1;
  23.  
  24.    /*
  25.     * Suppress an initial new-line in the output.
  26.     */
  27.    trail_nl = 1;
  28.    blank_ln = 1;
  29.    
  30.    while ((t = preproc()) != NULL) {
  31.       if (t->flag & LineChk) {
  32.          /*
  33.           * This token is significant with respect to outputing #line
  34.           *  directives.
  35.           */
  36.          nxt_line = t->line;
  37.          if (fname != t->fname  || line != nxt_line) {
  38.             /*
  39.              * We need a #line directive. Make sure it is preceeded by a
  40.              *  blank line.
  41.              */
  42.             if (!trail_nl) {
  43.                putc('\n', out_file);
  44.                ++line;
  45.                trail_nl = 1;
  46.                }
  47.             if (!blank_ln && (line != nxt_line || fname != t->fname)) {
  48.                putc('\n', out_file);
  49.                ++line;
  50.                blank_ln = 1;
  51.                }
  52.             /*
  53.              * Eliminate extra new-lines from the subsequent text before
  54.              *  inserting line directive. This make the output look better.
  55.              *  The line number for the directive will change if new-lines
  56.              *  are eliminated.
  57.              */
  58.             saved_whsp = NULL;
  59.             s = t->image;
  60.             while (t->tok_id == WhiteSpace && (*s == ' ' || *s == '\n' ||
  61.                  *s == '\t')) {
  62.                if (*s == '\n') {
  63.                   /*
  64.                    * Discard any white space before the new-line and update
  65.                    *  the line number.
  66.                    */
  67.                   free_t(saved_whsp);
  68.                   saved_whsp = NULL;
  69.                   t->image = s + 1;
  70.                   ++t->line;
  71.                   ++nxt_line;
  72.                   }
  73.                ++s;
  74.                if (*s == '\0') {
  75.                   /*
  76.                    * The end of the current white space token has been
  77.                    *  reached, see if the next token is also white space.
  78.                    */
  79.                   free_t(saved_whsp);
  80.                   t1 = preproc();
  81.                   if (t1 == NULL) {
  82.                      /*
  83.                       * We are at the end of the input. Don't output
  84.                       *  a #line directive, just make sure the output
  85.                       *  ends with a new-line.
  86.                       */
  87.                      free_t(t);
  88.                      if (!trail_nl)
  89.                         putc('\n', out_file);
  90.                      return;
  91.                      }
  92.                   /*
  93.                    * The previous token may contain non-new-line white
  94.                    *  space, if the new token is on the same line, save
  95.                    *  that previous token in case we want to print the
  96.                    *  white space (this will correctly indent the new
  97.                    *  token).
  98.                    */
  99.                   if (*(t->image) != '\0' && t->line == t1->line &&
  100.                        t->fname == t1->fname)
  101.                      saved_whsp = t;
  102.                   else {
  103.                      free_t(t);
  104.                      saved_whsp = NULL;
  105.                      }
  106.                   t = t1;
  107.                   s = t->image;
  108.                   nxt_line = t->line;
  109.                   }
  110.                }
  111.             if (line_cntrl) {
  112.                /*
  113.                 * We are supposed to insert #line directives where needed.
  114.                 *  However, one or two blank lines look better when they
  115.                 *  are enough to reestablish the correct line number.
  116.                 */
  117.                if (fname != t->fname  || line > nxt_line ||
  118.                     line + 2 < nxt_line) {
  119.                   /*
  120.                    * Normally a blank line is put after the #line
  121.                    *  directive; However, this requires decrementing
  122.                    *  the line number and a line number of 0 is not
  123.                    *  valid.
  124.                    */
  125.                   if (nxt_line > 1)
  126.                      fprintf(out_file, "#line %d \"", nxt_line - 1);
  127.                   else
  128.                      fprintf(out_file, "#line %d \"", nxt_line);
  129.                   for (s = t->fname; *s != '\0'; ++s) {
  130.                      if (*s == '"' || *s == '\\')
  131.                         putc('\\',out_file);
  132.                      putc(*s, out_file);
  133.                      }
  134.                   fprintf(out_file, "\"\n");
  135.                   if (nxt_line > 1)
  136.                      fprintf(out_file, "\n"); /* blank line after directive */
  137.                   trail_nl = 1;
  138.                   blank_ln = 1;
  139.                   }
  140.                else  /* adjust line number with blank lines */
  141.                   while (line < nxt_line) {
  142.                      putc('\n', out_file);
  143.                      ++line;
  144.                      if (trail_nl)
  145.                         blank_ln = 1;
  146.                      trail_nl = 1;
  147.                      }
  148.                }
  149.             /*
  150.              * See if we need to indent the next token with white space
  151.              *  saved while eliminating extra new-lines.
  152.              */
  153.             if (saved_whsp != NULL) {
  154.                fprintf(out_file, "%s", saved_whsp->image);
  155.                free_t(saved_whsp);
  156.                if (trail_nl) {
  157.                   blank_ln = 1;
  158.                   trail_nl = 0;
  159.                   }
  160.                }
  161.             line = t->line;
  162.             fname = t->fname;
  163.             }
  164.          }
  165.  
  166.       /*
  167.        * Print the image of the token.
  168.        */
  169.       if (t->tok_id == WhiteSpace) {
  170.          /*
  171.           * Keep track of trailing blank lines and new-lines. This
  172.           *  information is used to make the insertion of #line
  173.           *  directives more intellegent and to insure that the output
  174.           *  file ends with a new-line.
  175.           */
  176.          for (s = t->image; *s != '\0'; ++s) {
  177.             putc(*s, out_file);
  178.             switch (*s) {
  179.                case '\n':
  180.                   if (trail_nl)
  181.                      blank_ln = 1;
  182.                   trail_nl = 1;
  183.                   ++line;
  184.                   break;
  185.  
  186.                case ' ':
  187.                case '\t':
  188.                   if (trail_nl)
  189.                      blank_ln = 1;
  190.                   trail_nl = 0;
  191.                   break;
  192.  
  193.                default:
  194.                   trail_nl = 0;
  195.                }
  196.             }
  197.          }
  198.       else {
  199.          /*
  200.           * Add delimiters to string and character literals.
  201.           */
  202.          switch (t->tok_id) {
  203.             case StrLit:
  204.                fprintf(out_file, "\"%s\"", t->image);
  205.                break;
  206.             case LStrLit:
  207.                fprintf(out_file, "L\"%s\"", t->image);
  208.                break;
  209.             case CharConst:
  210.                fprintf(out_file, "'%s'", t->image);
  211.                break;
  212.             case LCharConst:
  213.                fprintf(out_file, "L'%s'", t->image);
  214.                break;
  215.             default:
  216.                fprintf(out_file, "%s", t->image);
  217.             }
  218.          trail_nl = 0;
  219.          blank_ln = 0;
  220.          }
  221.       free_t(t);
  222.       }
  223.  
  224.    /*
  225.     * Make sure output file ends with a new-line.
  226.     */
  227.    if (!trail_nl)
  228.       putc('\n', out_file);
  229.    }
  230.